#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'tian'
__data__ = '2021/12/4 17:00'
# software: PyCharm

import json

import xlrd

from django.db import transaction  # django事务，用于处理失败后不写入数据库
from django.shortcuts import render, HttpResponse, redirect, reverse
from django.http import JsonResponse
from django.http import FileResponse
from django.utils.encoding import escape_uri_path

from apps.app01 import models
from apps.app01.forms.mymodelform import ApiModelForm
from utils import RequestHandler
from utils.ShowTabHandler import ShowTabOpt
from apps.app01.templatetags.page import Pagination

# 发送邮件
from Interfaceautomationplatform import settings
from django.core.mail import send_mail


def list_api(request, pk):
    """
    用例列表,pk是项目的pk
    :param request:
    :return:
    """
    it_id = request.POST.get("it_id")
    url_it = "/item/list_api/{0}".format(it_id)
    it_obj = models.It.objects.filter(pk=pk).first()
    if request.method == "GET":
        api_obj_count = models.Api.objects.filter(api_sub_it_id=pk).count()
        current_page = request.GET.get("page")
        base_url = reverse("list_api", kwargs={"pk": pk})
        api_form_obj = ApiModelForm()
        paginator = Pagination(current_page=current_page, all_count=api_obj_count, base_url=base_url,
                               query_params=request.GET.copy())
        data_list = models.Api.objects.filter(api_sub_it_id=pk).order_by("-ascending_order")[
                    paginator.start:paginator.end]
        return render(request, "list_api.html",
                      {"api_obj": data_list, "it_obj": it_obj, "page": paginator, "all_count": api_obj_count,
                       "form": api_form_obj})

    # 添加测试用例
    form_data = ApiModelForm(request.POST)
    if form_data.is_valid():
        form_data.instance.api_url = "{0}{1}".format(it_obj.it_url, request.POST.get("api_url"))
        form_data.instance.api_sub_it_id = it_id
        form_data.save()
        return JsonResponse({"status": True, "data": url_it})
    return JsonResponse({"status": False, "error": form_data.errors})


def order_by(request):
    """
    置顶排序
    :param request:
    :return:
    """
    order_by = request.POST.get("name_order", "")
    aid = request.POST.get("aid", "")
    if order_by.isdecimal() and aid.isdecimal():
        order_by = int(order_by)
        if order_by >= 1 and order_by <= 100:
            models.Api.objects.filter(pk=aid).update(ascending_order=order_by)
            return JsonResponse({"status": True})
        return JsonResponse({"status": False, "error": "输入值范围错误"})
    return JsonResponse({"status": False, "error": "请输入数值类型"})


def edit_api(request, pk):
    """
    编辑测试用例
    pk是用例的pk
    :param request:
    :param pk:
    :return:
    """
    api_obj = models.Api.objects.filter(pk=pk).first() #pk是用例pk
    if request.method == "GET":
        api_form_obj = ApiModelForm(instance=api_obj)
        return render(request, "edit_api.html", {"form": api_form_obj, "api_obj": api_obj})
    form_data = ApiModelForm(request.POST, instance=api_obj)
    if form_data.is_valid():
        form_data.instance.__dict__["api_pass_status"] = 0
        form_data.instance.__dict__["api_run_status"] = 0
        form_data.instance.__dict__["api_report"] = ""
        form_data.save()
        return JsonResponse({"status": True, "data": "/item/list_api/{0}".format(api_obj.api_sub_it_id, )})
    return JsonResponse({"status": False, "error": form_data.errors})


def delete_api(request):
    """
    删除用例表
    :param request:
    :param pk:用例的pk
    :return:需要返回项目的pk值
    """
    pk = request.POST.get("fid")
    try:
        if request.method == "POST":
            api_obj = models.Api.objects.filter(pk=pk).first()
            api_obj.delete()
            return JsonResponse({"status": True})
    except Exception as error:
        pass
    return JsonResponse({"status": False, "error": "删除post请求,非法"})


def run_case(request, pk=0):
    """
    执行用例, pk是用例的Pk
    :param request:
    :return:
    """
    if request.is_ajax():  # 批量执行
        chk_value = request.POST.get("chk_value")
        # 反序列化
        chk_value = json.loads(chk_value)
        # 数据库取pk在chk_value中记录对象
        api_list = models.Api.objects.filter(pk__in=chk_value).order_by("-ascending_order")
        RequestHandler.run_case(api_list)
        return JsonResponse({"path": "/logs_list/"})
    else:  # 单个执行

        case_obj = models.Api.objects.filter(pk=pk).first() #模型对象
        RequestHandler.run_case([case_obj])
        return redirect("/logs_list/")


def download_case_report(request, pk):
    """下载用例的执行报告，pk是用例的pk"""
    api_obj = models.Api.objects.filter(pk=pk).first()
    # 下载
    response = FileResponse(api_obj.api_report)
    response['Content-Type'] = 'application/octet-stream' # 响应内容格式
    response['Content-Disposition'] = 'attachment;filename="{0}.{1}"'.format(escape_uri_path(api_obj.api_name), "html") # 响应内容已附件形式xiaz
    return response


def logs_list(request):
    """
    log日志主页
    :param request:
    :return:
    """
    if request.method == "GET":
        logs_obj_count = models.Logs.objects.all().count()
        current_page = request.GET.get("page")
        base_url = reverse("logs_list")
        paginator = Pagination(current_page=current_page, all_count=logs_obj_count, base_url=base_url,
                               query_params=request.GET.copy())
        data_list = models.Logs.objects.all()[paginator.start:paginator.end]
        return render(request, "logs_list.html",
                      {"logs_obj": data_list, "page": paginator, "all_count": logs_obj_count})
    return HttpResponse("ok")


def show_tab(request):
    """
    可视化
    :param request:
    :return:
    """
    if request.is_ajax():
        tab_obj = ShowTabOpt()
        data_dict = {}
        data_dict.update(tab_obj.pie())
        data_dict.update(tab_obj.line_simple())
        return JsonResponse(data_dict)
    return render(request, "show_tab.html")


def send_email(request):
    """
    发送普通邮件和发送带附件的邮件
    :param request:
    :return:
    """
    # 发送简单邮件
    send_mail(
        subject='这里是邮件标题',
        message='这里是邮件内容',
        from_email='tingyuweilou@163.com',
        # recipient_list=['1206180814@qq.com'],  # 收件人可以在这里写，也可以从settings.py导入
        recipient_list=settings.EMAIL_TO_USER_LIST,
        fail_silently=False
    )
    return HttpResponse('OK')

    # 发送带附件的邮件
    # msg = EmailMessage(
    #     subject='这是带附件的邮件标题',
    #     body='这是带附件的邮件内容',
    #     from_email=settings.EMAIL_HOST_USER,  # 发送人,从settings中获取
    #     to=settings.EMAIL_TO_USER_LIST  # 收件人，从settings中获取
    #     # from_email='tingyuweilou@163.com',  # 可以在这里写死，也可以从settings中获取
    #     # to=['1206180814@qq.com'] # 可以自己在这里写，也可以从settings中获取
    #
    # )
    # msg.attach_file('D:\pythonscript\Automatedtestplatform\sex.html')  # 需发送附件的路径
    # msg.send(fail_silently=False)
    # return HttpResponse('OK')


def upload(request, pk):
    """
    文件上传
    :param request:
    :return:
    """
    if request.method == "GET":
        return render(request, "upload.html", {"it_obj_pk": pk})

    try:
        if request.is_ajax():
            with transaction.atomic():  # 事务
                file_obj = request.FILES.get("f1")
                it_obj_pk = request.POST.get("it_obj_pk")
                book_obj = xlrd.open_workbook(filename=None, file_contents=file_obj.read())
                sheet = book_obj.sheet_by_index(0)
                title = sheet.row_values(0)
                data_list = [dict(zip(title, sheet.row_values(item))) for item in range(1, sheet.nrows)]
                for item in data_list:
                    if item["method"] == "post":
                        item_method = 2
                    else:
                        item_method = 1
                    models.Api.objects.create(
                        api_sub_it_id=it_obj_pk,
                        api_name=item["title"],
                        api_desc=item["desc"],
                        api_url=item["url"],
                        api_method=item_method,
                        api_params=item["params"],
                        api_expect=item["except"],
                        api_data=item["data"],
                    )
            return JsonResponse({"status": 200, "path": reverse("list_api", kwargs={"pk": it_obj_pk})})
    except Exception as error:
        return JsonResponse({"status": 500, "path": "/list_api/{0}/".format(it_obj_pk), "it_obj_pk": pk,
                             "errors": "这里只能上传[xls] or [xlsx]类型的表格，并且表格的字段要符合要求，错误详情:{0}".format(error)
                             })


def preview(request, pk):
    """
    测试报告预览 ,pk是log记录的Pk
    :param request:
    :return:
    """
    log_obj = models.Logs.objects.filter(pk=pk).first()
    if request.method == "POST":
        request.POST.get("report_pk")
        # 下载
        response = FileResponse(log_obj.log_report)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="{0}.{1}"'.format(
            escape_uri_path(log_obj.log_sub_it.it_name),
            "html")
        return response
    return render(request, "preview.html", {"log_obj": log_obj})
